#include <Windows.h>
#include <WindowsX.h>
#include <tchar.h>
#include "resource.h"

struct SThreadInfo
{
	UINT	nMax;
	HWND	hListBox;
};

LONG dwNum = 0;
DWORD CALLBACK ThreadProc(LPVOID lpData)
{
	SThreadInfo* pThreadInfo = (SThreadInfo*)lpData;
	
	TCHAR szTmp[MAX_PATH];
	LONG nData = InterlockedIncrement(&dwNum);
	_stprintf(szTmp, _T("0x%0X #%d start...\n"), GetCurrentThreadId(), nData);

	ListBox_AddString(pThreadInfo->hListBox, szTmp);

	for (int ii = 0; ii < pThreadInfo->nMax; ii++)
	{
		_stprintf(szTmp, _T("0x%0X print %d"), GetCurrentThreadId(), ii + 1);
		ListBox_AddString(pThreadInfo->hListBox, szTmp);
		SendMessage(pThreadInfo->hListBox, WM_VSCROLL, SB_BOTTOM, 0);
	}
	
	_stprintf(szTmp, _T("0x%0X #%d done...\n"), GetCurrentThreadId(), nData);
	ListBox_AddString(pThreadInfo->hListBox, szTmp);
	SendMessage(pThreadInfo->hListBox, WM_VSCROLL, SB_BOTTOM, 0);

	if (0 == InterlockedDecrement(&dwNum))
	{
		_stprintf(szTmp, _T("All threads work finished\n"));
		MessageBox(NULL, szTmp, _T("Demo0093"), MB_OK);
	}
	
	return 0;
}

int CALLBACK DlgProc(HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	static const UINT nCount = 4;
	static HANDLE hThreads[nCount];
	static SThreadInfo ThreadInfo[4];

	switch (nMsg)
	{
		case WM_INITDIALOG:
		{
			SetWindowText(hDlg, _T("Demo0093"));

			UINT nWidth		= GetSystemMetrics(SM_CXSCREEN);
			UINT nHeight	= GetSystemMetrics(SM_CYSCREEN);
			RECT rtClient;
			GetClientRect(hDlg, &rtClient);
			SetWindowPos(hDlg, NULL, (nWidth - (rtClient.right - rtClient.left)) / 2, (nHeight - (rtClient.bottom - rtClient.top)) / 2, 0, 0, SWP_NOSIZE);
			
			break;
		}
		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case IDC_BTNSTART:
				{	
					ThreadInfo[0].nMax			= 5000;
					ThreadInfo[0].hListBox		= GetDlgItem(hDlg, IDC_LIST1);
					ThreadInfo[1].nMax			= 2000;
					ThreadInfo[1].hListBox		= GetDlgItem(hDlg, IDC_LIST2);
					ThreadInfo[2].nMax			= 3000;
					ThreadInfo[2].hListBox		= GetDlgItem(hDlg, IDC_LIST3);
					ThreadInfo[3].nMax			= 4000;
					ThreadInfo[3].hListBox		= GetDlgItem(hDlg, IDC_LIST4);

					hThreads[0] = CreateThread(NULL, 0, ThreadProc, (LPVOID)&ThreadInfo[0], 0, 0);
					hThreads[1] = CreateThread(NULL, 0, ThreadProc, (LPVOID)&ThreadInfo[1], 0, 0);
					hThreads[2] = CreateThread(NULL, 0, ThreadProc, (LPVOID)&ThreadInfo[2], 0, 0);
					hThreads[3] = CreateThread(NULL, 0, ThreadProc, (LPVOID)&ThreadInfo[3], 0, 0);
					
					break;
				}
				case IDC_BTNEXIT:
				{
					EndDialog(hDlg, 0);
					break;
				}
			}

			break;
		}
		case WM_CLOSE:
		{
			PostQuitMessage(0);
			break;
		}
	}

	return 0;
}

BOOL WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPTSTR szCmdLine, int nShowCmd)
{
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);

	return TRUE;
}